package boardgamer.yavalath.common.ai;

import boardgamer.yavalath.common.YavalathGameState;
import boardgamer.yavalath.common.YavalathTile;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

public class Node implements Comparable<Node> {
  private int wins = 0;
  private int visits = 0;

  private YavalathTile yavalathTile;
  // The state of the game AFTER the move indicated by yavalathTile is made.
  private YavalathGameState yavalathGameState;
  private ImmutableList<Node> children;

  public Node(YavalathTile yavalathTile, YavalathGameState yavalathGameState) {
    //Preconditions.checkState(!yavalathTile.hasOwner(), "Cannot have a tile with a owner in the search tree.");
    this.yavalathTile = yavalathTile;
    this.yavalathGameState = yavalathGameState;
  }
  
  public int getVisits() {
    return visits;
  }

  public YavalathGameState getYavalathGameState() {
    return yavalathGameState;
  }

  public YavalathTile getYavalathTile() {
    return yavalathTile;
  }

  public ImmutableList<Node> getChildren() {
    return children;
  }

  public void setChildren(ImmutableList<Node> children) {
    this.children = children;
  }

  public void update(int val) {
    Preconditions.checkState(Math.abs(val) <= 1, "Invalid update");
    visits++;
    wins += val;
  }

  public double getWinRate() {
    //checkState(visits > 0, "Should not happen");
    return visits == 0
        ? 0
        : ((double) wins) / visits;
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof Node)) {
      return false;
    }

    Node that = (Node) o;
    return this.yavalathTile == that.yavalathTile;
  }

  @Override
  public int compareTo(Node that) {
    return Double.compare(this.getWinRate(), that.getWinRate());
  }
}